home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Docs / Sources / UFileBasedDocument.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  70.8 KB  |  2,535 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UFileBasedDocument.cp 
  3. // Copyright © 1984-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __UFILEBASEDDOCUMENT__
  7. #include "UFileBasedDocument.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. #ifndef __GEOMETRY__
  13. #include "Geometry.h"
  14. #endif
  15.  
  16. #ifndef __UAPPLEEVENTS__
  17. #include "UAppleEvents.h"
  18. #endif
  19.  
  20. #ifndef __UCLIPBOARDMGR__
  21. #include "UClipboardMgr.h"
  22. #endif
  23.  
  24. #if qContainer
  25.     #ifndef __UCONTAINER__
  26.     #include "UContainer.h"
  27.     #endif
  28. #endif
  29.  
  30. #ifndef __UDESIGNATOR__
  31. #include "UDesignator.h"
  32. #endif
  33.  
  34. #ifndef __UDISPATCHER__
  35. #include "UDispatcher.h"
  36. #endif
  37.  
  38. #ifndef __UERRORMGR__
  39. #include "UErrorMgr.h"
  40. #endif
  41.  
  42. #ifndef __UFILE__
  43. #include "UFile.h"
  44. #endif
  45.  
  46. #ifndef __UFILESTREAM__
  47. #include "UFileStream.h"
  48. #endif
  49.  
  50. #ifndef __UITERATOR__
  51. #include "UIterator.h"
  52. #endif
  53.  
  54. #ifndef __ULIST__
  55. #include "UList.h"
  56. #endif
  57.  
  58. #ifndef __UMACAPPGLOBALS__
  59. #include "UMacAppGlobals.h"
  60. #endif
  61.  
  62. #ifndef __UMACAPPUTILITIES__
  63. #include "UMacAppUtilities.h"
  64. #endif
  65.  
  66. #ifndef __UMAILER__
  67. //    #include "UMailer.h"
  68. #endif
  69.  
  70. #ifndef __UMEMORY__
  71. #include "UMemory.h"
  72. #endif
  73.  
  74. #if !qPowerPC
  75.     #ifndef __UPATCH__
  76.     #include "UPatch.h"
  77.     #endif
  78. #endif
  79.  
  80. #ifndef __UPRINTHANDLER__
  81. #include "UPrintHandler.h"
  82. #endif
  83.  
  84. #ifndef __USCRIPTING__
  85. #include "UScripting.h"
  86. #endif
  87.  
  88. #ifndef __USTREAM__
  89. #include "UStream.h"
  90. #endif
  91.  
  92. #ifndef __UVIEW__
  93. #include "UView.h"
  94. #endif
  95.  
  96. #ifndef __UWINDOW__
  97. #include "UWindow.h"
  98. #endif
  99.  
  100. // CALib
  101.  
  102. #if qContainer
  103.     #ifndef _CALIB_
  104.     #include "CALib.h"
  105.     #endif
  106. #endif
  107.  
  108. // Toolbox
  109.  
  110. #ifndef __AEREGISTRY__
  111. #include <AERegistry.h>
  112. #endif
  113.  
  114. #ifndef __ERRORS__
  115. #include <Errors.h>
  116. #endif
  117.  
  118. #ifndef __FOLDERS__
  119. #include <Folders.h>
  120. #endif
  121.  
  122. #ifndef __RESOURCES__
  123. #include <Resources.h>
  124. #endif
  125.  
  126. #ifndef __STANDARDFILE__
  127. #include <StandardFile.h>
  128. #endif
  129.  
  130. #ifndef __TOOLUTILS__
  131. #include <ToolUtils.h>
  132. #endif
  133.  
  134. // ANSI
  135.  
  136. #ifndef __STDIO__
  137. #include <stdio.h>
  138. #endif
  139.  
  140. //========================================================================================
  141. // CLASS TSaveFileDocCommand
  142. //========================================================================================
  143. #undef Inherited
  144. #define Inherited TSaveDocCommand
  145.  
  146. #pragma segment MASelCommand
  147. MA_DEFINE_CLASS_M1(TSaveFileDocCommand, Inherited);
  148.  
  149. //----------------------------------------------------------------------------------------
  150. // TSaveFileDocCommand constructor
  151. //----------------------------------------------------------------------------------------
  152. #pragma segment MASelCommand
  153.  
  154. TSaveFileDocCommand::TSaveFileDocCommand()
  155.     : fSaveFile(NULL)
  156. {
  157. }
  158.  
  159. //----------------------------------------------------------------------------------------
  160. // TSaveFileDocCommand destructor
  161. //----------------------------------------------------------------------------------------
  162. #pragma segment MADestructorRes
  163.  
  164. TSaveFileDocCommand::~TSaveFileDocCommand()
  165. {
  166.     FreeIfObject(fSaveFile);
  167. }
  168.  
  169. //----------------------------------------------------------------------------------------
  170. // TSaveFileDocCommand::ISaveDocCommand: 
  171. //----------------------------------------------------------------------------------------
  172. #pragma segment MASelCommand
  173.  
  174. void TSaveFileDocCommand::ISaveFileDocCommand(CommandNumber itsCommandNumber,
  175.                                               TDocument* itsDocument)
  176. {
  177.     this->ISaveDocCommand(itsCommandNumber, itsDocument);
  178.  
  179.     TFileBasedDocument* aDocument = (TFileBasedDocument*)fDocument;
  180.     
  181.     // See if we already have a place to save the file
  182.     Boolean hasFile = aDocument->FileExists();
  183.     
  184.     if (hasFile && fIdentifier != cSaveAs && fIdentifier != cSaveCopy)
  185.     {
  186.         fSaveFile = aDocument->DoMakeFile(itsCommandNumber);
  187.         fSaveFile->SpecifyWithFile(aDocument->GetFile());
  188.     }
  189.     else if (!hasFile
  190.              || itsCommandNumber == cSaveAs
  191.              || itsCommandNumber == cSaveCopy)
  192.     {
  193.         if (itsCommandNumber != cSaveCopy)
  194.             itsCommandNumber = cSaveAs;
  195.  
  196.         fSaveFile = aDocument->DoMakeFile(itsCommandNumber);
  197.     
  198.         // Ask the user for the destination file location and name.
  199.         FailOSErr(MAInteractWithUser());
  200.         FailInfo fi2;
  201.         Try(fi2)
  202.         {
  203.             // If this fails (i.e. user cancels) then we want it to be caught
  204.             // in elsewhere with a more appropriate error code.
  205.             aDocument->RequestFileName(itsCommandNumber, FALSE, fSaveFile);
  206.             fi2.Success();
  207.         }
  208.         else // Recover
  209.         {
  210.             if (fi2.error == noErr && fi2.message == messageCancelled)
  211.                 FailOSErr(userCanceledErr);
  212.             fi2.ReSignal();
  213.         }
  214.     }
  215.     
  216.     fIdentifier = itsCommandNumber;
  217. }
  218.  
  219. //----------------------------------------------------------------------------------------
  220. // TSaveFileDocCommand::ISaveDocCommand: 
  221. //----------------------------------------------------------------------------------------
  222. #pragma segment MASelCommand
  223.  
  224. void TSaveFileDocCommand::ISaveFileDocCommand(TDocument* itsDocument,
  225.                                               TAppleEvent* message,
  226.                                               TAppleEvent* reply)
  227. {
  228.     FailInfo fi;
  229.     Try(fi)
  230.     {
  231.         this->ISaveDocCommand(itsDocument, message, reply);
  232.         
  233.         TFileBasedDocument* aDocument = (TFileBasedDocument*)fDocument;
  234.         
  235.         if (message->HasParameter(keyAESaveCopy) && message->ReadBoolean(keyAESaveCopy))
  236.             fIdentifier = cSaveCopy;
  237.     
  238.         // Determine where to save the file from the AppleEvent message.
  239.         if (message->HasParameter(keyAEFile))
  240.         {
  241.             DescType        returnedType;
  242.             FSSpec            theFSSpec;
  243.             Size            actualSize;
  244.     
  245.             FailOSErr(AEGetParamPtr(&message->fMessage, keyAEFile, typeFSS, &returnedType, (Ptr) & theFSSpec, sizeof(theFSSpec), &actualSize));
  246.             fSaveFile = aDocument->DoMakeFile(fIdentifier);
  247.             fSaveFile->Specify(theFSSpec);
  248.             fIdentifier = cSaveAs;
  249.         }
  250.         else
  251.         {
  252.             // No but do we already have a file wherein we can save?
  253.             TFileBasedDocument*    aDocument = (TFileBasedDocument*)fDocument;
  254.             Boolean hasFile = aDocument->FileExists();
  255.     
  256.             if (hasFile)
  257.             {
  258.                 fSaveFile = aDocument->DoMakeFile(fIdentifier);
  259.                 fSaveFile->SpecifyWithFile(aDocument->GetFile());
  260.             }
  261.             else
  262.             {
  263.                 fIdentifier = cSaveAs;
  264.         
  265.                 fSaveFile = aDocument->DoMakeFile(fIdentifier);
  266.             
  267.                 // Ask the user for the destination file location and name.
  268.                 FailOSErr(MAInteractWithUser());
  269.                 FailInfo fi2;
  270.                 Try(fi2)
  271.                 {
  272.                     // If this fails (i.e. user cancels) then we want it to be caught
  273.                     // in elsewhere with a more appropriate error code.
  274.                     aDocument->RequestFileName(fIdentifier, FALSE, fSaveFile);
  275.                     fi2.Success();
  276.                 }
  277.                 else // Recover
  278.                 {
  279.                     if (fi2.error == noErr && fi2.message == messageCancelled)
  280.                         FailOSErr(userCanceledErr);
  281.                     fi2.ReSignal();
  282.                 }
  283.             }
  284.         }
  285.         fi.Success();
  286.     }
  287.     else                                // Recover
  288.     {
  289.         // If this fails because user cancels then we want it 
  290.         // to be caught with a more appropriate error code.
  291.         if (fi.error == noErr && fi.message == messageCancelled)
  292.             fi.error = userCanceledErr;
  293.         //this->SetValidationError(fi.error);    // In case we are linked.
  294.         fi.ReSignal();
  295.     }
  296.  
  297.     if (message->HasParameter(keyAEFileType))
  298.         fSaveFile->fFileType = message->ReadType(keyAEFileType);
  299. }
  300.  
  301. //----------------------------------------------------------------------------------------
  302. // TSaveFileDocCommand::MakeAppleEvent: 
  303. //----------------------------------------------------------------------------------------
  304. #pragma segment MACommandRes
  305.  
  306. TAppleEvent* TSaveFileDocCommand::MakeAppleEvent()
  307. {
  308.     // We have to save the file specifier in the AppleEvent.
  309.     MAVolatileInit(TAppleEvent*, theEvent, NULL);
  310.     CTempDesc theDocDesc;
  311.  
  312.     theEvent = Inherited::MakeAppleEvent();
  313.  
  314.     FailInfo fi;
  315.     Try(fi)
  316.     {
  317.         // Which file to store it into.
  318.         if (fSavingState != kDontSave && fSaveFile != NULL)
  319.         {
  320.             CAEDesc        aSaveFileDesc;
  321.             FSSpec        theFileSpec;
  322.             fSaveFile->GetFileSpec(theFileSpec);
  323.             aSaveFileDesc.PutFSSpec(theFileSpec);
  324.             theEvent->WriteParameter(keyAEFile, aSaveFileDesc);
  325.         }
  326.  
  327.         fi.Success();
  328.     }
  329.     else                                // Recover
  330.     {
  331.         theEvent = (TAppleEvent *)FreeIfObject(theEvent);
  332.         fi.ReSignal();
  333.     }
  334.     return theEvent;
  335. }
  336.  
  337. //----------------------------------------------------------------------------------------
  338. // TSaveFileDocCommand::DoIt: 
  339. //----------------------------------------------------------------------------------------
  340. #pragma segment MAClose
  341.  
  342. void TSaveFileDocCommand::DoIt()
  343. {
  344.     if (fDocument && fSavingState != kDontSave)
  345.     {
  346. //        FailInfo fi;
  347. //        Try(fi)
  348. //        {
  349.         Boolean makingCopy = (fIdentifier == cSaveCopy);
  350.  
  351.         if (fDocument->fCommitOnSave || (!makingCopy))
  352.             fDocument->CommitLastCommand();
  353.         
  354.         // Set the document's TFile object so that it saves in the correct place.
  355.         TFileBasedDocument* aFileDocument = (TFileBasedDocument*)fDocument;
  356.         MAVolatileInit(TFile*, existingFileCopy, NULL);
  357.         existingFileCopy = aFileDocument->DoMakeFile(fIdentifier);
  358.     
  359.         FailInfo fi2;
  360.         Try(fi2)
  361.         {
  362.             existingFileCopy->SpecifyWithFile(aFileDocument->GetFile());
  363.             aFileDocument->GetFile()->SpecifyWithFile(fSaveFile);
  364.             Boolean currFileExists = aFileDocument->fFileExists;
  365.             // Test to see if the destination file is there.
  366.             aFileDocument->fFileExists = (fSaveFile->GetModificationDate() != 0);
  367.     
  368.             aFileDocument->SaveDocument(cSave);
  369.     
  370.             if (fIdentifier == cSaveCopy)
  371.             {
  372.                 // Restore the existing file info since we just made a copy.
  373.                 aFileDocument->fFileExists = currFileExists;
  374.                 aFileDocument->GetFile()->SpecifyWithFile(existingFileCopy);
  375.             }
  376.             FreeIfObject(existingFileCopy);
  377.             fi2.Success();
  378.         }
  379.         else // Recover
  380.         {
  381.             FreeIfObject(existingFileCopy);
  382.             fi2.ReSignal();
  383.         }
  384. //            fi.Success();
  385. //        }
  386. //        else
  387. //        {
  388. //            this->SetValidationError(fi.error);    // In case we are linked.
  389. //            fi.ReSignal();
  390. //        }
  391.     }
  392. }
  393.  
  394.  
  395. //========================================================================================
  396. // CLASS TCloseFileDocCommand
  397. //========================================================================================
  398. #undef Inherited
  399. #define Inherited TCloseDocCommand
  400.  
  401. #pragma segment MASelCommand
  402. MA_DEFINE_CLASS_M1(TCloseFileDocCommand, Inherited);
  403.  
  404. //----------------------------------------------------------------------------------------
  405. // TCloseFileDocCommand constructor
  406. //----------------------------------------------------------------------------------------
  407. #pragma segment MASelCommand
  408.  
  409. TCloseFileDocCommand::TCloseFileDocCommand()
  410. {
  411.     fCloseFile = NULL;
  412. }
  413.  
  414. //----------------------------------------------------------------------------------------
  415. // TCloseFileDocCommand destructor
  416. //----------------------------------------------------------------------------------------
  417. #pragma segment MADestructorRes
  418.  
  419. TCloseFileDocCommand::~TCloseFileDocCommand()
  420. {
  421.     fCloseFile = (TFile*) FreeIfObject(fCloseFile);
  422. }
  423.  
  424. //----------------------------------------------------------------------------------------
  425. // TCloseFileDocCommand::ICloseDocCommand: 
  426. //----------------------------------------------------------------------------------------
  427. #pragma segment MASelCommand
  428.  
  429. void TCloseFileDocCommand::ICloseFileDocCommand(CommandNumber itsCommandNumber,
  430.                                                 TDocument* itsDocument)
  431. {
  432.     this->ICloseDocCommand(itsCommandNumber, itsDocument);
  433.     
  434.     fSaveCommand = cSave;
  435.     
  436.     // Are we saving?
  437.     if (fSavingState == kDoSave)
  438.     {
  439.         FailInfo fi;
  440.         Try(fi)
  441.         {
  442.             FailOSErr(MAInteractWithUser());
  443.             TFileBasedDocument*    aDocument = (TFileBasedDocument*)fDocument;
  444.             Boolean hasFile = aDocument->FileExists();
  445.     
  446.             // Get where to save the file
  447.             
  448.             if (hasFile)
  449.             {
  450.                 fCloseFile = aDocument->DoMakeFile(itsCommandNumber);
  451.                 fCloseFile->SpecifyWithFile(aDocument->GetFile());
  452.             }
  453.             else
  454.             {
  455.                 // We have to ask for the save location.
  456.                 fSaveCommand = cSaveAs;
  457.                 
  458.                 fCloseFile = aDocument->DoMakeFile(cSaveAs);
  459.             
  460.                 // Ask the user for the destination file location and name.
  461.                 aDocument->RequestFileName(cSaveAs, FALSE, fCloseFile);
  462.             }
  463.             fi.Success();
  464.         }
  465.         else // Recover
  466.         {
  467.             // If this fails because user cancels then we want it 
  468.             // to be caught with a more appropriate error code.
  469.             if (fi.error == noErr && fi.message == messageCancelled)
  470.                 fi.error = userCanceledErr;
  471.             //this->SetValidationError(fi.error);    // In case we are linked.
  472.             fi.ReSignal();
  473.         }
  474.     }
  475. }
  476.  
  477. //----------------------------------------------------------------------------------------
  478. // TCloseFileDocCommand::ICloseFileDocCommand: 
  479. //----------------------------------------------------------------------------------------
  480. #pragma segment MASelCommand
  481.  
  482. void TCloseFileDocCommand::ICloseFileDocCommand(TDocument* itsDocument,
  483.                                                 TAppleEvent* message,
  484.                                                 TAppleEvent* reply)
  485. {
  486.     this->ICloseDocCommand(itsDocument, message, reply);
  487.  
  488.     fSaveCommand = cSave;
  489.     
  490.     if (fSavingState != kDontSave)
  491.     {
  492.         FailInfo fi;
  493.         Try(fi)
  494.         {
  495.             // Does the AppleEvent specifically say where to save the file;
  496.             if (message->HasParameter(keyAEFile))
  497.             {
  498.                 DescType        returnedType;
  499.                 FSSpec            theFSSpec;
  500.                 Size            actualSize;
  501.         
  502.                 FailOSErr(AEGetParamPtr(&message->fMessage, keyAEFile, typeFSS, &returnedType, (Ptr) & theFSSpec, sizeof(theFSSpec), &actualSize));
  503.                 TFileBasedDocument*    aDocument = (TFileBasedDocument*)fDocument;
  504.                 fCloseFile = aDocument->DoMakeFile(fIdentifier);
  505.                 fCloseFile->Specify(theFSSpec);
  506.                 fSaveCommand = cSaveAs;
  507.             }
  508.             else
  509.             {
  510.                 // No but do we already have a file wherein we can save?
  511.                 TFileBasedDocument*    aDocument = (TFileBasedDocument*)fDocument;
  512.                 Boolean hasFile = aDocument->FileExists();
  513.         
  514.                 // Get where to save the file
  515.                 
  516.                 if (hasFile)
  517.                 {
  518.                     fCloseFile = aDocument->DoMakeFile(cClose);
  519.                     fCloseFile->SpecifyWithFile(aDocument->GetFile());
  520.                 }
  521.                 else
  522.                 {
  523.                     fSaveCommand = cSaveAs;
  524.                     fCloseFile = aDocument->DoMakeFile(cSaveAs);
  525.                 
  526.                     // Ask the user for the destination file location and name.
  527.                     FailOSErr(MAInteractWithUser());
  528.                     aDocument->RequestFileName(cSaveAs, FALSE, fCloseFile);
  529.                 }
  530.             }
  531.             fi.Success();
  532.         }
  533.         else // Recover
  534.         {
  535.             // If this fails because user cancels then we want it 
  536.             // to be caught with a more appropriate error code.
  537.             if (fi.error == noErr && fi.message == messageCancelled)
  538.                 fi.error = userCanceledErr;
  539.             //this->SetValidationError(fi.error);    // In case we are linked.
  540.             fi.ReSignal();
  541.         }
  542.     }
  543. }
  544.  
  545. //----------------------------------------------------------------------------------------
  546. // TCloseFileDocCommand::MakeAppleEvent: 
  547. //----------------------------------------------------------------------------------------
  548. #pragma segment MACommandRes
  549.  
  550. TAppleEvent* TCloseFileDocCommand::MakeAppleEvent()
  551. {
  552.     // We have to save the file specifier in the AppleEvent.
  553.     MAVolatileInit(TAppleEvent*, theEvent, NULL);
  554.     CTempDesc theDocDesc;
  555.  
  556.     theEvent = Inherited::MakeAppleEvent();
  557.  
  558.     FailInfo fi;
  559.     Try(fi)
  560.     {
  561.         // Which file to store it into.
  562.         if (fSavingState != kDontSave && fCloseFile != NULL)
  563.         {
  564.             CAEDesc        aCloseFileDesc;
  565.             FSSpec        theFileSpec;
  566.             fCloseFile->GetFileSpec(theFileSpec);
  567.             aCloseFileDesc.PutFSSpec(theFileSpec);
  568.             theEvent->WriteParameter(keyAEFile, aCloseFileDesc);
  569.         }
  570.         fi.Success();
  571.     }
  572.     else                                // Recover
  573.     {
  574.         theEvent = (TAppleEvent *)FreeIfObject(theEvent);
  575.         fi.ReSignal();
  576.     }
  577.     return theEvent;
  578. }
  579.  
  580. //----------------------------------------------------------------------------------------
  581. // TCloseFileDocCommand::DoIt: 
  582. //----------------------------------------------------------------------------------------
  583. #pragma segment MAClose
  584.  
  585. void TCloseFileDocCommand::DoIt()
  586. {
  587.     if (fDocument)
  588.     {
  589. //        FailInfo fi;
  590. //        Try(fi)
  591. //        {
  592.         // Some documents want us to specifically ask if they should be saved.
  593.         if (fSavingState == kAskSave)
  594.         {
  595.             short poseResult = fDocument->PoseSaveDialog();
  596.             switch (poseResult)
  597.             {
  598.                 case kNoButton:
  599.                     fSavingState = kDontSave;
  600.                     break;
  601.                 case kYesButton:
  602.                     fSavingState = kDoSave;
  603.                     break;
  604.                 case cancel:
  605.                     FailOSErr(userCanceledErr);
  606.                     break;
  607.             }
  608.         }
  609.         
  610.         if (fSavingState == kDoSave)
  611.         {
  612.             fDocument->CommitLastCommand();
  613.         
  614.             // Set the document's TFile object so that it saves in the correct place.
  615.             TFileBasedDocument* aFileDocument = (TFileBasedDocument*)fDocument;
  616.             MAVolatileInit(TFile*, existingFileCopy, NULL);
  617.             existingFileCopy = aFileDocument->DoMakeFile(fSaveCommand);
  618.         
  619.             FailInfo fi3;
  620.             Try(fi3)
  621.             {
  622.                 existingFileCopy->SpecifyWithFile(aFileDocument->GetFile());
  623.                 aFileDocument->GetFile()->SpecifyWithFile(fCloseFile);
  624.                 Boolean currFileExists = aFileDocument->fFileExists;
  625.                 aFileDocument->fFileExists = (fCloseFile->GetModificationDate() != 0);
  626.         
  627.                 aFileDocument->SaveDocument(cSave);
  628.         
  629.                 FreeIfObject(existingFileCopy);
  630.                 fi3.Success();
  631.             }
  632.             else // Recover
  633.             {
  634.                 FreeIfObject(existingFileCopy);
  635.                 fi3.ReSignal();
  636.             }
  637.         }
  638.  
  639.         // If there is actually some saving to do it should have already been done.
  640.         fDocument->SetChangeCount(0);
  641.         fDocument->CloseAndFree();
  642.         fDocument = NULL;
  643. //            fi.Success();
  644. //        }
  645. //        else
  646. //        {
  647. //            this->SetValidationError(fi.error);    // In case we are linked.
  648. //            fi.ReSignal();
  649. //        }
  650.     }
  651. }
  652.  
  653. //========================================================================================
  654. // CLASS TFileBasedDocument
  655. //========================================================================================
  656. #undef Inherited
  657. #define Inherited TDocument
  658.  
  659. #pragma segment MAOpen
  660. MA_DEFINE_CLASS_M1(TFileBasedDocument, Inherited);
  661.  
  662. //----------------------------------------------------------------------------------------
  663. // TFileBasedDocument constructor
  664. //----------------------------------------------------------------------------------------
  665. #pragma segment MAOpen
  666.  
  667. TFileBasedDocument::TFileBasedDocument() :
  668. #if qContainer
  669.     fContainerDocument(NULL),
  670.     fContainerOffset(0),
  671.     fContainerLength(0),
  672.     fRootWindowRef(NULL),
  673. #endif
  674.     fFile(NULL),
  675.     fFileExists(FALSE)
  676. {
  677.     fHowToSave = svtAskUser;
  678.     fScrapType = '    ';                            // need constant kNoScrapType
  679. }
  680.  
  681. //----------------------------------------------------------------------------------------
  682. // TFileBasedDocument::IFileBasedDocument: 
  683. //----------------------------------------------------------------------------------------
  684. #pragma segment MAOpen
  685.  
  686. void TFileBasedDocument::IFileBasedDocument(TFile* itsFile, OSType itsScrapType)
  687. {
  688.     this->IDocument();
  689.  
  690.     fFile = itsFile;
  691.     fScrapType = itsScrapType;
  692.  
  693.     FailInfo fi;
  694.     Try(fi)
  695.     {
  696. #if qContainer
  697.         gDispatcher->AddCADocument(this); //add this to the App's list of ContainerDoc's
  698.         fODPartViewList = NewList();     //set up the ODView listing
  699.         fODPartViewList->IList();
  700. #endif
  701.         if (!fFile)
  702.             fFile = this->DoMakeFile(cNew);
  703.         fi.Success();
  704.     }
  705.     else    // Recover
  706.     {
  707.         this->Free();
  708.         fi.ReSignal();
  709.     }
  710. }
  711.  
  712. //----------------------------------------------------------------------------------------
  713. // TFileBasedDocument::DoMakeFile: 
  714. //----------------------------------------------------------------------------------------
  715. #pragma segment MAOpen
  716.  
  717. TFile* TFileBasedDocument::DoMakeFile(CommandNumber itsCommandNumber)
  718. {
  719.     return gDispatcher->DoMakeFile(itsCommandNumber);
  720. }
  721.  
  722. //----------------------------------------------------------------------------------------
  723. // TFileBasedDocument::DoMakeFileHandler: 
  724. //----------------------------------------------------------------------------------------
  725.  
  726. //----------------------------------------------------------------------------------------
  727. // TFileBasedDocument::Free: 
  728. //----------------------------------------------------------------------------------------
  729. #pragma segment MAClose
  730.  
  731. TFileBasedDocument::~TFileBasedDocument()
  732. {
  733. #if qContainer
  734.     if (fContainerDocument)
  735.     {
  736.         gDispatcher->DeleteCADocument(this); //delete this from the App's list of ContainerDoc's
  737.         CACloseDocument(fContainerDocument);
  738.         fContainerDocument = NULL;
  739.     }
  740. #endif
  741.     if (fFile)
  742.     {
  743.         this->CloseFile();
  744.         fFile->Free();
  745.         fFile = NULL;
  746.     }
  747. }
  748.  
  749. //----------------------------------------------------------------------------------------
  750. // TFileBasedDocument::DoInitialState:
  751. //----------------------------------------------------------------------------------------
  752. #pragma segment AOpen
  753.  
  754. void TFileBasedDocument::DoInitialState()
  755. {
  756.     // don't need to call Inherited method because it is empty
  757.  
  758. #if qContainer
  759.     if (gContainerLib)
  760.     {
  761.         // ••• MDR - The IFileBasedDocument method creates a file with an
  762.         // empty file spec so the following test is always try.  But since its file
  763.         // spec doesn't identify a valid file the CACreateDocument fails.  I've temporarily
  764.         // forced the test in order to force a file spec to be initialized.
  765.         FSSpec fileSpec;
  766.         if (FALSE && fFile)        // ••• MDR - Note the FALSE
  767.             fileSpec = fFile->fFileSpec;
  768.         else
  769.         {
  770.             CStr15("\pUntitled").CopyTo(fileSpec.name);
  771.             // ••• MDR - Changed to use the temporary items folder rather than the desktop folder.
  772.             FailOSErr(FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder, &fileSpec.vRefNum, &fileSpec.parID));
  773.             
  774.             MakeDatedUniqueFSSpec(&fileSpec);
  775.             
  776.             SetTitle(fileSpec.name);
  777.         }
  778.         fContainerDocument = CACreateDocument(&fileSpec, NULL);
  779.         if (fContainerDocument)
  780.         {
  781.             CASetDocumentKind(fContainerDocument, 0 /* kDrawShapesDocumentKind */);
  782.             this->RegisterCAHandlers();
  783.         }
  784.         // ••• MDR - Need to determine the document kind by calling a member function.
  785.     }
  786. #endif
  787. }
  788.  
  789. //----------------------------------------------------------------------------------------
  790. // TFileBasedDocument::FindDocument: 
  791. //----------------------------------------------------------------------------------------
  792. #pragma segment MAFile
  793.  
  794. Boolean TFileBasedDocument::FindDocument(TFile* aFile)// override 
  795. {
  796.     return FileAlreadyOpen(aFile);
  797. }
  798.  
  799. //----------------------------------------------------------------------------------------
  800. // TFileBasedDocument::CheckFile: 
  801. //----------------------------------------------------------------------------------------
  802. #pragma segment MAFile
  803.  
  804. void TFileBasedDocument::CheckFile(ResNumber rsrcId,
  805.                                    short rsrcIndex,
  806.                                    Boolean reverting)
  807. {
  808.     OSErr err = FileChanged(reverting);    // don't care about the file type if saving 
  809.     if (err == errFileChanged)
  810.     {
  811.         FailOSErr(MAInteractWithUser());
  812.         CStr255 s;
  813.         GetIndString(s, rsrcId, rsrcIndex);
  814.         ParamText(fTitle, s, gEmptyString, gEmptyString);
  815.         if (MacAppAlert(phFileChanged, NULL) == cancel)
  816.             Failure(noErr, messageCancelled);
  817.     }
  818.     else if ((err != noErr) && reverting)
  819.         Failure(err, 0);
  820. }
  821.  
  822. //----------------------------------------------------------------------------------------
  823. // TFileBasedDocument::Close: 
  824. //----------------------------------------------------------------------------------------
  825. #pragma segment MAClose
  826.  
  827. void TFileBasedDocument::Close()
  828. {
  829.     long changeCount;
  830.     short poseResult = kYesButton;
  831.     
  832. #if qDebug
  833.     if (gClipboardMgr->fClipWindow->fDocument == this)
  834.         ProgramBreak("Attempt to close clipboard document");
  835. #endif
  836.  
  837.     changeCount = this->GetChangeCount();
  838.     if (changeCount && fAskOnClose)
  839.     {
  840.         poseResult = this->PoseSaveDialog();
  841.         if (poseResult == cancel)
  842.             Failure(noErr, messageCancelled);
  843.     }
  844.  
  845.     if (changeCount)
  846.     {
  847.         if (poseResult == kYesButton)
  848.             this->SaveDocument(cClose);                // Will fail if unable to save 
  849.         else if (poseResult == kNoButton)
  850.             this->Abandon();
  851.     }
  852.     Inherited::Close();
  853. }
  854.  
  855. //----------------------------------------------------------------------------------------
  856. // TFileBasedDocument::DoAESave
  857. //----------------------------------------------------------------------------------------
  858. #pragma segment MAScriptingRes
  859.  
  860. void TFileBasedDocument::DoAESave(TAppleEvent* message,
  861.                                   TAppleEvent* reply)
  862. {
  863.     // Generate a save document command.
  864.     Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  865.     Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  866.     TSaveFileDocCommand* aSaveFileDocCommand = NULL;
  867.  
  868.     aSaveFileDocCommand = new TSaveFileDocCommand();
  869.     aSaveFileDocCommand->ISaveFileDocCommand(this, message, reply);
  870.  
  871.     // Immediately process the command rather than post it.
  872.     aSaveFileDocCommand->Process();
  873.  
  874.     TemporaryAllocation(oldTempAlloc);
  875.     AllocateObjectsFromPerm(oldObjectPerm);
  876. }
  877.  
  878. //----------------------------------------------------------------------------------------
  879. // TFileBasedDocument::DoAEClose: 
  880. //----------------------------------------------------------------------------------------
  881. #pragma segment MAScriptingRes
  882.  
  883. void TFileBasedDocument::DoAEClose(TAppleEvent* message,
  884.                                    TAppleEvent* reply)
  885. {
  886.     Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  887.     Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  888.     TCloseFileDocCommand* aCloseFileDocCommand = NULL;
  889.     
  890.     aCloseFileDocCommand = new TCloseFileDocCommand;
  891.     aCloseFileDocCommand->ICloseFileDocCommand(this, message, reply);
  892.     
  893.     // Immediately process the command rather than post it.
  894.     aCloseFileDocCommand->Process();
  895.  
  896.     TemporaryAllocation(oldTempAlloc);
  897.     AllocateObjectsFromPerm(oldObjectPerm);
  898. }
  899.  
  900. //----------------------------------------------------------------------------------------
  901. // TFileBasedDocument::DoNeedDiskSpace: 
  902. //----------------------------------------------------------------------------------------
  903. #pragma segment MAWriteFile
  904.  
  905. void TFileBasedDocument::DoNeedDiskSpace(TFile* itsFile,
  906.                                          long& dataForkBytes,
  907.                                          long& rsrcForkBytes)
  908. {
  909.     if (itsFile->HasRsrcFork())
  910.     {
  911.         CStr255 theName;
  912.         CStr255 theMessage;
  913.         
  914.         gDispatcher->GetApplicationName(theName);
  915.         this->GetFinderMessage(theMessage);
  916.         
  917.         if (!theMessage.IsEmpty())
  918.             rsrcForkBytes += kRsrcTypeOverhead + kRsrcOverhead + theMessage.Length() + 1;
  919.         else if (!theName.IsEmpty())
  920.             rsrcForkBytes += kRsrcTypeOverhead + kRsrcOverhead + theName.Length() + 1;
  921.  
  922.         if (fSavePrintInfo && fPrintInfo)
  923.             rsrcForkBytes += kRsrcTypeOverhead + kRsrcOverhead + TPrintHandler::gPrintHandler->GetSavePrintInfoSize(fPrintInfo, itsFile, itsFile->HasRsrcFork());
  924.         
  925.         if (fSaveUserSelection)
  926.         {
  927.             TDesignator* theSelection = this->GetUserSelection();
  928.             if (theSelection)
  929.             {
  930.                 TCountingStream* aStream;
  931.                 aStream = new TCountingStream;
  932.                 aStream->ICountingStream();
  933.                 aStream->WriteStreamObject(theSelection);
  934.                 rsrcForkBytes += kRsrcTypeOverhead + kRsrcOverhead + aStream->GetSize();
  935.                 aStream->Free();
  936.             }
  937.         }
  938.         rsrcForkBytes += kRsrcFileOverhead;
  939.     }
  940.     else if (fSavePrintInfo && fPrintInfo)
  941.         dataForkBytes += TPrintHandler::gPrintHandler->GetSavePrintInfoSize(fPrintInfo, itsFile, itsFile->HasRsrcFork());
  942.  
  943. #if qContainer
  944.     dataForkBytes += sizeof(CAOffset) + sizeof(CASize);
  945.     
  946.     if (gContainerLib && fContainerDocument)
  947.         dataForkBytes += fContainerLength;
  948. #endif
  949. }
  950.  
  951. //----------------------------------------------------------------------------------------
  952. // TFileBasedDocument::RegainControl: 
  953. //----------------------------------------------------------------------------------------
  954. #pragma segment MADocumentRes
  955.  
  956. void TFileBasedDocument::RegainControl()
  957. {
  958.     if (ValidateFileSpec())
  959.     {
  960.         CStr63 fileName;
  961.         GetFileName(fileName);
  962.         SetTitle(fileName);
  963.     }
  964. }
  965.  
  966. //----------------------------------------------------------------------------------------
  967. // TFileBasedDocument::DoRead: 
  968. //----------------------------------------------------------------------------------------
  969. #pragma segment MAReadFile
  970.  
  971. void TFileBasedDocument::DoRead(TFile* aFile,
  972.                                 Boolean forPrinting)
  973. {
  974. #if qContainer
  975.     // ••• MDR
  976.     // Always place the container information at the beginning of the file
  977.     // so that the embedded objects can be read even if the rest of the document
  978.     // cannot be understood.
  979.     TFileStream* aFileStream = new TFileStream;
  980.     aFileStream->IFileStream(aFile);
  981.  
  982.     aFileStream->ReadBytes(&fContainerOffset, sizeof(CAOffset));
  983.     aFileStream->ReadBytes(&fContainerLength, sizeof(CASize));
  984.  
  985.     // Now stream in the embedded parts.
  986.     if (gContainerLib && (fContainerLength > 0))
  987.     {
  988.         FSSpec theFileSpec;
  989.         aFile->GetFileSpec(theFileSpec);
  990.         fContainerDocument = CAOpenDocument(&theFileSpec, NULL, fContainerOffset, fContainerLength);
  991.  
  992.         // ••• MDR - Don't we need to close the document here?
  993.  
  994.         aFileStream->SetPosition(fContainerOffset + fContainerLength);
  995.         
  996.         // ••• MDR - I don't really like doing the registration with CALib
  997.         // here but this seems to be the bottleneck.  Review this.
  998.         
  999.     }
  1000.     FreeIfObject(aFileStream);
  1001. #endif
  1002.     
  1003.     if (fSavePrintInfo)
  1004.         this->DoReadPrintInfo(aFile, forPrinting);
  1005.     
  1006.     if (fSaveUserSelection)
  1007.         this->DoReadSelection(aFile, forPrinting);
  1008.  
  1009. #if qAttachable
  1010.     if (fSaveAttachedScript)
  1011.         this->DoReadScript(aFile, forPrinting);
  1012. #endif
  1013. }
  1014.  
  1015. //----------------------------------------------------------------------------------------
  1016. // TFileBasedDocument::DoReadPrintInfo: 
  1017. //----------------------------------------------------------------------------------------
  1018. #pragma segment MAReadFile
  1019.  
  1020. void TFileBasedDocument::DoReadPrintInfo(TFile* aFile,
  1021.                                                 Boolean /* forPrinting */)
  1022. {
  1023.     if (FileExists())
  1024.         fPrintInfo = TPrintHandler::gPrintHandler->RestorePrintInfo(aFile, aFile->HasRsrcFork());
  1025. }
  1026.  
  1027. #if qAttachable
  1028.  
  1029. //----------------------------------------------------------------------------------------
  1030. // TFileBasedDocument::DoReadScript: 
  1031. //----------------------------------------------------------------------------------------
  1032. #pragma segment MAReadFile
  1033.  
  1034. void TFileBasedDocument::DoReadScript(TFile* aFile,
  1035.                                       Boolean /* forPrinting */)
  1036. {
  1037.     Handle scriptInfo = NULL;
  1038.     
  1039.     if (HasAppleScript() && FileExists())
  1040.     {
  1041.         if (aFile->HasRsrcFork())
  1042.         {
  1043.             if (aFile->IsRsrcForkOpen())
  1044.             {
  1045.                 CTempDesc scriptDesc;
  1046.                 
  1047.                 scriptDesc.ReadFrom(aFile, kScriptInfoRsrcType, kScriptInfoRsrcID);
  1048.                 if (scriptDesc.fAEDesc.descriptorType != typeNull)
  1049.                     this->SetOSAScript(scriptDesc);
  1050.             }
  1051.         }
  1052.         else
  1053.         {
  1054.             MAVolatileInit(TFileStream*, aFileStream, new TFileStream);
  1055.             aFileStream->IFileStream(aFile);
  1056.             
  1057.             FailInfo fi;
  1058.             Try(fi)
  1059.             {
  1060.                 this->ReadOSAScript(aFileStream);
  1061.                 fi.Success();
  1062.             }
  1063.             else
  1064.             {
  1065.                 aFileStream = (TFileStream *)FreeIfObject(aFileStream);
  1066.                 fi.ReSignal();
  1067.             }
  1068.     
  1069.             aFileStream = (TFileStream *)FreeIfObject(aFileStream);
  1070.         }
  1071.     }
  1072. }
  1073.  
  1074. #endif // qAttachable
  1075.  
  1076. //----------------------------------------------------------------------------------------
  1077. // TFileBasedDocument::DoReadSelection: 
  1078. //----------------------------------------------------------------------------------------
  1079. #pragma segment MAReadFile
  1080.  
  1081. void TFileBasedDocument::DoReadSelection(TFile* aFile,
  1082.                                          Boolean forPrinting)
  1083. {
  1084.     MAVolatileInit(Handle, theSelectionRsrc, NULL);
  1085.     if (FileExists() && aFile->HasRsrcFork() && aFile->IsRsrcForkOpen())
  1086.     {
  1087.         short saveRefNum = aFile->UseResource();
  1088.         if (ResError() == noErr)
  1089.             theSelectionRsrc = Get1Resource(kDesignatorResType, kSelectionRsrcID);
  1090.         MAUseResFile(saveRefNum);
  1091.     }
  1092.     
  1093.     if (theSelectionRsrc && !forPrinting)
  1094.     {
  1095.         TObject* aUserSelection = NULL;        // No need to be volatile: it is passed by reference
  1096.         
  1097.         // read in the associated designator 
  1098.         MAVolatileInit(THandleStream*, aHandleStream, new THandleStream);
  1099.         aHandleStream->IHandleStream(theSelectionRsrc, 10);
  1100.         
  1101.         FailInfo fi;
  1102.         Try(fi)
  1103.         {
  1104.             if (aHandleStream->ReadStreamObject(aUserSelection))
  1105.                 this->SetUserSelection((TDesignator*) aUserSelection);
  1106. #if qDebugMsg
  1107.             else
  1108.             {
  1109.                 ProgramBreak("###Unknown TDesignator for selection.");
  1110.             }
  1111. #endif
  1112.         
  1113.             aHandleStream = (THandleStream*) FreeIfObject(aHandleStream);
  1114.             ReleaseResource(theSelectionRsrc);
  1115.  
  1116.             fi.Success();
  1117.         }
  1118.         else    // Recover
  1119.         {
  1120.             aUserSelection = FreeIfObject(aUserSelection);
  1121.             aHandleStream = (THandleStream*) FreeIfObject(aHandleStream);
  1122.             ReleaseResource(theSelectionRsrc);
  1123.  
  1124.             fi.ReSignal();
  1125.         }
  1126.     }
  1127. }
  1128.  
  1129. //----------------------------------------------------------------------------------------
  1130. // TFileBasedDocument::AboutToSaveFile: 
  1131. //----------------------------------------------------------------------------------------
  1132. #pragma segment MAWriteFile
  1133.  
  1134. void TFileBasedDocument::AboutToSaveFile(TFile* /* theSaveFile */,
  1135.                                                 CommandNumber /* itsCmd */,
  1136.                                                 Boolean& /* makingCopy */)
  1137. {
  1138. }
  1139.  
  1140. //----------------------------------------------------------------------------------------
  1141. // TFileBasedDocument::DoWrite: 
  1142. //----------------------------------------------------------------------------------------
  1143. #pragma segment MAWriteFile
  1144.  
  1145. void TFileBasedDocument::DoWrite(TFile* aFile,
  1146.                                         Boolean makingCopy)
  1147. {
  1148.     this->DoWriteFinderString(aFile, makingCopy);
  1149.     
  1150. #if qContainer
  1151.     TFileStream*    aFileStream = new TFileStream;
  1152.     aFileStream->IFileStream(aFile);
  1153.             
  1154.     fContainerOffset = aFileStream->GetSize() + sizeof(CAOffset) + sizeof(CASize);
  1155.     fContainerLength = 0;
  1156.     
  1157.     aFileStream->WriteBytes(&fContainerOffset, sizeof(CAOffset));
  1158.     aFileStream->WriteBytes(&fContainerLength, sizeof(CASize));
  1159.     
  1160.     if (gContainerLib && fContainerDocument)
  1161.     {
  1162.         FSSpec newFileSpec;
  1163.         aFile->GetFileSpec(newFileSpec);
  1164.         CASaveDocument(fContainerDocument, &newFileSpec, NULL, fContainerOffset, &fContainerLength);
  1165.     }
  1166.     
  1167.     if (fContainerLength > 0)
  1168.     {
  1169.         aFileStream->SetPosition(fContainerOffset - sizeof(CASize));
  1170.         aFileStream->WriteBytes(&fContainerLength, sizeof(CASize));
  1171.         aFileStream->SetPosition(fContainerOffset + fContainerLength);
  1172.     }
  1173.     
  1174.     aFileStream = (TFileStream *)FreeIfObject(aFileStream);
  1175. #endif
  1176.     
  1177.     if (fSavePrintInfo && fPrintInfo)
  1178.         this->DoWritePrintInfo(aFile, makingCopy);
  1179.     
  1180.     if (fSaveUserSelection)
  1181.         this->DoWriteSelection(aFile, makingCopy);
  1182.  
  1183. #if qAttachable
  1184.     if (fSaveAttachedScript)
  1185.         this->DoWriteScript(aFile, makingCopy);
  1186. #endif
  1187. }
  1188.  
  1189. //----------------------------------------------------------------------------------------
  1190. // TFileBasedDocument::DoWriteFinderString: 
  1191. //----------------------------------------------------------------------------------------
  1192. #pragma segment MAWriteFile
  1193.  
  1194. void TFileBasedDocument::DoWriteFinderString(TFile* aFile,
  1195.                                                  Boolean /* makingCopy */)
  1196. {
  1197.     if (aFile->HasRsrcFork())
  1198.     {
  1199.         CStr255 theName;
  1200.         CStr255 theMessage;
  1201.         
  1202.         gDispatcher->GetApplicationName(theName);
  1203.         this->GetFinderMessage(theMessage);
  1204.         
  1205.         if (!theMessage.IsEmpty())
  1206.         {
  1207.             MAVolatile(CStringHandle, messageHandle);
  1208.  
  1209.             Boolean oldPerm = PermAllocation(TRUE);
  1210.             messageHandle = (CStringHandle)NewString(theMessage);
  1211.             PermAllocation(oldPerm);
  1212.             FailNIL((Handle) messageHandle);
  1213.             
  1214.             FailInfo fi;
  1215.             Try(fi)
  1216.             {
  1217.                 MAAddResource((Handle) messageHandle, kFinderStringType, kFinderMessageID, gEmptyString);
  1218.                 FailResError();
  1219.                 fi.Success();
  1220.             }
  1221.             else
  1222.             {
  1223.                 messageHandle = (CStringHandle) DisposeIfHandle((Handle) messageHandle);
  1224.                 fi.ReSignal();
  1225.             }
  1226.         }
  1227.         else if (!theName.IsEmpty())
  1228.         {
  1229.             MAVolatile(CStringHandle, nameHandle);
  1230.  
  1231.             Boolean oldPerm = PermAllocation(TRUE);
  1232.             nameHandle = (CStringHandle)NewString(theName);
  1233.             PermAllocation(oldPerm);
  1234.             FailNIL((Handle) nameHandle);
  1235.                         
  1236.             FailInfo fi;
  1237.             Try(fi)
  1238.             {
  1239.                 MAAddResource((Handle) nameHandle, kFinderStringType, kFinderApplicationNameID, gEmptyString);
  1240.                 FailResError();
  1241.                 fi.Success();
  1242.             }
  1243.             else
  1244.             {
  1245.                 nameHandle = (CStringHandle) DisposeIfHandle((Handle) nameHandle);
  1246.                 fi.ReSignal();
  1247.             }
  1248.         }
  1249.     }
  1250. }
  1251.  
  1252. //----------------------------------------------------------------------------------------
  1253. // TFileBasedDocument::DoWritePrintInfo: 
  1254. //----------------------------------------------------------------------------------------
  1255. #pragma segment MAWriteFile
  1256.  
  1257. void TFileBasedDocument::DoWritePrintInfo(TFile* aFile,
  1258.                                           Boolean /* makingCopy */)
  1259. {
  1260.     if (fPrintInfo)
  1261.         TPrintHandler::gPrintHandler->SavePrintInfo(fPrintInfo, aFile, aFile->HasRsrcFork());
  1262. #if qDebug
  1263.     else
  1264.         ProgramBreak("No print record in document!");
  1265. #endif
  1266. }
  1267.  
  1268. #if qAttachable
  1269.  
  1270. //----------------------------------------------------------------------------------------
  1271. // TFileBasedDocument::DoWriteScript: 
  1272. //----------------------------------------------------------------------------------------
  1273. #pragma segment MAWriteFile
  1274.  
  1275. void TFileBasedDocument::DoWriteScript(TFile* aFile,
  1276.                                        Boolean /* makingCopy */)
  1277. {
  1278.     if (this->HasOSAScript())
  1279.     {
  1280.         if (aFile->HasRsrcFork())
  1281.         {
  1282.             CStr255    resourceName;
  1283.             fOSAScript->WriteOSAScript(aFile, kScriptInfoRsrcType, kScriptInfoRsrcID, resourceName);
  1284.         }
  1285.         else
  1286.         {
  1287.             MAVolatileInit(TFileStream*, aFileStream, new TFileStream);
  1288.             aFileStream->IFileStream(aFile);
  1289.             
  1290.             FailInfo fi;
  1291.             Try(fi)
  1292.             {
  1293.                 this->WriteOSAScript(aFileStream, typeOSAGenericStorage);
  1294.                 fi.Success();
  1295.             }
  1296.             else
  1297.             {
  1298.                 aFileStream = (TFileStream *)FreeIfObject(aFileStream);
  1299.                 fi.ReSignal();
  1300.             }
  1301.             aFileStream = (TFileStream *)FreeIfObject(aFileStream);
  1302.         }
  1303.     }
  1304. }
  1305.  
  1306. #endif // qAttachable
  1307.  
  1308. //----------------------------------------------------------------------------------------
  1309. // TFileBasedDocument::DoWriteSelection: 
  1310. //----------------------------------------------------------------------------------------
  1311. #pragma segment MAWriteFile
  1312.  
  1313. void TFileBasedDocument::DoWriteSelection(TFile* aFile,
  1314.                                                  Boolean /* makingCopy */)
  1315. {
  1316.     TDesignator* theSelection = this->GetUserSelection();
  1317.     if (theSelection && aFile->HasRsrcFork())
  1318.     {
  1319.         // set up for failure handler
  1320.         MAVolatileInit(Handle, theSelectionRsrc, NULL);
  1321.  
  1322.         // allocate a handle for the resource
  1323.         theSelectionRsrc = NewPermHandle(50); //!!! SRF - what's this magic number?
  1324.  
  1325.         // write the user selection to the handle
  1326.         FailInfo fi;
  1327.         Try(fi)
  1328.         {
  1329.             MAVolatileInit(THandleStream*, aHandleStream, new THandleStream);
  1330.             aHandleStream->IHandleStream(theSelectionRsrc, 10);
  1331.  
  1332.             FailInfo innerfi;
  1333.             Try(innerfi)
  1334.             {
  1335.                 // write out the associated designator 
  1336.                 aHandleStream->WriteStreamObject(theSelection);
  1337.                 aHandleStream->Free();
  1338.  
  1339.                 innerfi.Success();
  1340.             }
  1341.             else
  1342.             {
  1343.                 aHandleStream = (THandleStream*) FreeIfObject(aHandleStream);
  1344.     
  1345.                 innerfi.ReSignal();
  1346.             }
  1347.     
  1348.             // add the new selection resource
  1349.             MAAddResource(theSelectionRsrc, kDesignatorResType, kSelectionRsrcID, gEmptyString);
  1350.             FailResError();
  1351.  
  1352.             fi.Success();
  1353.         }
  1354.         else    // Recover
  1355.         {
  1356.             theSelectionRsrc = DisposeIfHandle(theSelectionRsrc);
  1357.  
  1358.             fi.ReSignal();
  1359.         }
  1360.     }
  1361. }
  1362.  
  1363. //----------------------------------------------------------------------------------------
  1364. // TFileBasedDocument::CloseFile: 
  1365. //----------------------------------------------------------------------------------------
  1366. #pragma segment MADocumentRes
  1367.  
  1368. void TFileBasedDocument::CloseFile()
  1369. {
  1370.     if (fFile)
  1371.         fFile->CloseFile();
  1372. }
  1373.  
  1374. //----------------------------------------------------------------------------------------
  1375. // TFileBasedDocument::ReadDocument: 
  1376. //----------------------------------------------------------------------------------------
  1377. #pragma segment MAReadFile
  1378.  
  1379. void TFileBasedDocument::ReadDocument(Boolean forPrinting) // override 
  1380. {
  1381.     CStr63 fileName;
  1382.     GetFileName(fileName);
  1383.     fTitle = fileName;
  1384.     ReadFile(forPrinting);
  1385.     this->SetChangeCount(0);
  1386. }
  1387.  
  1388. //----------------------------------------------------------------------------------------
  1389. // TFileBasedDocument::ReadStationery: 
  1390. //----------------------------------------------------------------------------------------
  1391. #pragma segment MAReadFile
  1392.  
  1393. void TFileBasedDocument::ReadStationery(TFile* itsNewFile) // override 
  1394. {
  1395.     ReadFile(kForDisplay);
  1396.     SetFile(itsNewFile);
  1397.     this->SetChangeCount(1);
  1398. }
  1399.  
  1400. //----------------------------------------------------------------------------------------
  1401. // TFileBasedDocument::RevertDocument: 
  1402. //----------------------------------------------------------------------------------------
  1403. #pragma segment MAReadFile
  1404.  
  1405. void TFileBasedDocument::RevertDocument()
  1406. {
  1407.     FailInfo fi;
  1408.     Try(fi)
  1409.     {
  1410.         this->CheckFile(kIDBuzzString, bzRevertAnyways, TRUE);
  1411.  
  1412.             this->CommitLastCommand();
  1413.  
  1414.         this->FreeData();
  1415.  
  1416.         if (FileExists())
  1417.             ReadFile(kForDisplay);
  1418.         else
  1419.         {
  1420.             CObjectIterator iter(fViewList);
  1421.             TPrintHandler* itsPrintHandler;
  1422.         
  1423.             for (TView* view = (TView*) iter.FirstObject(); iter.More(); view = (TView*) iter.NextObject())
  1424.                 if ((itsPrintHandler = view->GetPrintHandler()) != NULL)
  1425.                     itsPrintHandler->Reset();
  1426.  
  1427.             this->DoInitialState();
  1428.         }
  1429.  
  1430.         this->SetChangeCount(0);
  1431.         fi.Success();
  1432.     }
  1433.     else    // Recover
  1434.     {
  1435.         this->Free();                            // Free the document since the data
  1436.                                                 // may not be in any state to redisplay
  1437.         if (fi.error == fnfErr)
  1438.             fi.error = errRevertFNF;
  1439.             
  1440.         if (fi.message == 0)
  1441.             gErrorParm3 = fTitle;
  1442.             
  1443.         FailNewMessage(fi.error, fi.message, messageRevertFailed);
  1444.     }
  1445. }
  1446.  
  1447.  
  1448. //----------------------------------------------------------------------------------------
  1449. // TFileBasedDocument::GetSaveLocation
  1450. //----------------------------------------------------------------------------------------
  1451. #pragma segment MASelCommand
  1452.  
  1453. void TFileBasedDocument::GetSaveLocation(CommandNumber itsCommandNumber, CAEDesc& theSaveDesc)
  1454. // Creates an CAEDesc describing where the document would be saved
  1455. {
  1456.     Boolean askForFilename = !FileExists() || ((itsCommandNumber != cSave) && (itsCommandNumber != cClose));
  1457.     Boolean makingCopy = itsCommandNumber == cSaveCopy;
  1458.     TFile* theSaveFile = NULL;
  1459.     theSaveFile = this->DoMakeFile(itsCommandNumber);
  1460.     if (askForFilename)
  1461.             RequestFileName(itsCommandNumber, makingCopy, theSaveFile);
  1462.         else
  1463.             theSaveFile->SpecifyWithFile(GetFile());
  1464.     FailOSErr(AECreateDesc(typeFSS,(Ptr)&theSaveFile->fFileSpec,sizeof(FSSpec), theSaveDesc));
  1465.     FreeIfObject(theSaveFile);
  1466. }
  1467.  
  1468. //----------------------------------------------------------------------------------------
  1469. // TFileBasedDocument::IsChanged: 
  1470. //----------------------------------------------------------------------------------------
  1471. #pragma segment MADocumentRes
  1472.  
  1473. Boolean TFileBasedDocument::IsChanged()
  1474. {
  1475. #if qContainer
  1476.     return (Inherited::IsChanged()
  1477.             || (gContainerLib
  1478.                 && this->GetContainer()
  1479.                 && CAHasDocumentChanged(fContainerDocument)));
  1480. #else
  1481.     return Inherited::IsChanged();
  1482. #endif
  1483. }
  1484.  
  1485. //----------------------------------------------------------------------------------------
  1486. // TFileBasedDocument::DoSave
  1487. //----------------------------------------------------------------------------------------
  1488. #pragma segment MASelCommand
  1489.  
  1490. void TFileBasedDocument::DoSave(CommandNumber itsCommandNumber)
  1491. {
  1492.     // Generate a save document command.
  1493.     MAVolatileInit(Boolean, oldTempAlloc, TemporaryAllocation(TRUE));
  1494.     MAVolatileInit(Boolean, oldObjectPerm, AllocateObjectsFromPerm(FALSE));
  1495.     MAVolatileInit(TSaveFileDocCommand*, aSaveFileDocCommand, NULL);
  1496.  
  1497.     FailInfo fi;
  1498.     Try(fi)
  1499.     {
  1500.         aSaveFileDocCommand = new TSaveFileDocCommand;
  1501.         aSaveFileDocCommand->ISaveFileDocCommand(itsCommandNumber, this);
  1502.         aSaveFileDocCommand->fUseAppleEvent = TRUE;    // This is the difference!
  1503.         this->PostCommand(aSaveFileDocCommand);
  1504.  
  1505.         TemporaryAllocation(oldTempAlloc);
  1506.         AllocateObjectsFromPerm(oldObjectPerm);
  1507.  
  1508.         fi.Success();
  1509.     }
  1510.     else                                // Recover
  1511.     {
  1512.         FreeIfObject(aSaveFileDocCommand);
  1513.         TemporaryAllocation(oldTempAlloc);
  1514.         AllocateObjectsFromPerm(oldObjectPerm);
  1515.  
  1516.         if (fi.error != userCanceledErr)
  1517.             fi.ReSignal();
  1518.     }
  1519. }
  1520.  
  1521. //----------------------------------------------------------------------------------------
  1522. // TFileBasedDocument::SaveDocument: 
  1523. //----------------------------------------------------------------------------------------
  1524. #pragma segment MAWriteFile
  1525.  
  1526. void TFileBasedDocument::SaveDocument(CommandNumber itsCommandNumber)
  1527. {
  1528.     Boolean askForFilename = (itsCommandNumber == cClose) && !fFileExists;
  1529.     Boolean makingCopy = itsCommandNumber == cSaveCopy;
  1530.     Boolean copyFInfo = fFileExists;
  1531.  
  1532.     if (copyFInfo)
  1533.         this->CheckFile(kIDBuzzString, bzSaveAnyways, FALSE);
  1534.  
  1535.     if (fCommitOnSave || (!makingCopy) )
  1536.         this->CommitLastCommand();
  1537.  
  1538.     SaveFile(itsCommandNumber, askForFilename, copyFInfo, makingCopy);
  1539. }
  1540.  
  1541. //----------------------------------------------------------------------------------------
  1542. // TFileBasedDocument::MakeCloseCommand: 
  1543. //----------------------------------------------------------------------------------------
  1544. #pragma segment MAClose
  1545.  
  1546. TCloseDocCommand* TFileBasedDocument::MakeCloseCommand()
  1547. {
  1548.     TCloseFileDocCommand* aCloseCommand = new TCloseFileDocCommand;
  1549.     aCloseCommand->ICloseFileDocCommand(cClose, this);
  1550.     return aCloseCommand;
  1551. }
  1552.  
  1553. //----------------------------------------------------------------------------------------
  1554. // TFileBasedDocument::FileHasBeenSaved: 
  1555. //----------------------------------------------------------------------------------------
  1556. #pragma segment MAWriteFile
  1557.  
  1558. void TFileBasedDocument::FileHasBeenSaved(const CStr255& newName)
  1559. {
  1560.     this->SetChangeCount(0);
  1561.  
  1562.     if (fTitle != newName)
  1563.         this->SetTitle(newName);
  1564. }
  1565.  
  1566. //----------------------------------------------------------------------------------------
  1567. // TFileBasedDocument::SFPutParms: 
  1568. //----------------------------------------------------------------------------------------
  1569. #pragma segment MAWriteFile
  1570.  
  1571. void TFileBasedDocument::SFPutParms(CommandNumber itsCommandNumber,
  1572.                                     CStr255& prompt,
  1573.                                     CStr255& defaultName,
  1574.                                     ResNumber& dlgID,
  1575.                                     CPoint& where,
  1576.                                     ProcPtr& dlgHook,
  1577.                                     ProcPtr& modalFilter,
  1578.                                     Ptr& activeList,
  1579.                                     ProcPtr& activateProc,
  1580.                                     StandardFileReply* /*reply*/,
  1581.                                     void*& yourDataPtr)
  1582. {
  1583.     short idx;
  1584.  
  1585.     dlgID = sfPutDialogID;
  1586.     where = kBestSystemLocation;
  1587.  
  1588.     switch (itsCommandNumber)
  1589.     {
  1590.         case cSave:
  1591.         case cSaveAs:
  1592.             idx = bzSaveAs;
  1593.             break;
  1594.             
  1595.         case cSaveCopy:
  1596.             idx = bzSaveCopy;
  1597.             break;
  1598.             
  1599.         default:
  1600.             idx = 0;
  1601.             break;
  1602.     }
  1603.  
  1604.     if (idx == 0)
  1605.         prompt.Empty();
  1606.     else
  1607.         GetIndString(prompt, kIDBuzzString, idx);
  1608.         
  1609.     this->GetTitle(defaultName);
  1610.  
  1611.     dlgHook = NULL;
  1612.     modalFilter = (ProcPtr) gModalFilterYDProcPtr;
  1613.     activeList = NULL;
  1614.     activateProc = NULL;
  1615.     yourDataPtr = NULL;
  1616. }
  1617.  
  1618. //----------------------------------------------------------------------------------------
  1619. // TFileBasedDocument::GetFileHandler: 
  1620. //----------------------------------------------------------------------------------------
  1621.  
  1622. //----------------------------------------------------------------------------------------
  1623. // TFileBasedDocument::SetTitle: 
  1624. //----------------------------------------------------------------------------------------
  1625. #pragma segment MADocumentRes
  1626.  
  1627. void TFileBasedDocument::SetTitle(const CStr255& aTitle)
  1628. {
  1629.     Inherited::SetTitle(aTitle);
  1630.     SetFileName(aTitle);
  1631. }
  1632.  
  1633.  
  1634. //----------------------------------------------------------------------------------------
  1635. // TFileBasedDocument::GetFinderMessage: 
  1636. //----------------------------------------------------------------------------------------
  1637. #pragma segment MAWriteFile
  1638.  
  1639. void TFileBasedDocument::GetFinderMessage(CStr255& theMessage)
  1640. {
  1641.     theMessage.Empty();
  1642. }
  1643.  
  1644. //----------------------------------------------------------------------------------------
  1645. // TFileBasedDocument::MakeCloseCommand: 
  1646. //----------------------------------------------------------------------------------------
  1647. #pragma segment MAClose
  1648.  
  1649. void TFileBasedDocument::DoClose(CommandNumber aCommand,
  1650.                                  Boolean useAppleEvent)
  1651. {
  1652.     MAVolatileInit(Boolean, oldTempAlloc, TemporaryAllocation(TRUE));
  1653.     MAVolatileInit(Boolean, oldObjectPerm, AllocateObjectsFromPerm(FALSE));
  1654.     MAVolatileInit(TCloseFileDocCommand*, aCloseFileDocCommand, NULL);
  1655.  
  1656.     FailInfo fi;
  1657.     Try(fi)
  1658.     {
  1659.         aCloseFileDocCommand = new TCloseFileDocCommand;
  1660.         aCloseFileDocCommand->ICloseFileDocCommand(aCommand, this);
  1661.         aCloseFileDocCommand->fUseAppleEvent = useAppleEvent;
  1662.         
  1663.         this->PostCommand(aCloseFileDocCommand);
  1664.  
  1665.         TemporaryAllocation(oldTempAlloc);
  1666.         AllocateObjectsFromPerm(oldObjectPerm);
  1667.  
  1668.         fi.Success();
  1669.     }
  1670.     else                                // Recover
  1671.     {
  1672.         TemporaryAllocation(oldTempAlloc);
  1673.         AllocateObjectsFromPerm(oldObjectPerm);
  1674.         FreeIfObject(aCloseFileDocCommand);
  1675.     }
  1676. }
  1677.  
  1678. //----------------------------------------------------------------------------------------
  1679. // File Handling
  1680. //----------------------------------------------------------------------------------------
  1681.  
  1682. //----------------------------------------------------------------------------------------
  1683. // TFileBasedDocument::FileAlreadyOpen: 
  1684. //----------------------------------------------------------------------------------------
  1685. #pragma segment MADocumentRes
  1686.  
  1687. Boolean TFileBasedDocument::FileAlreadyOpen(TFile* aFile)
  1688. {
  1689.     if (fFileExists)
  1690.         return fFile->IsSameFile(aFile);
  1691.     else
  1692.         return FALSE;
  1693. }
  1694.  
  1695. //----------------------------------------------------------------------------------------
  1696. // TFileBasedDocument::FileChanged: 
  1697. //----------------------------------------------------------------------------------------
  1698. #pragma segment MAFile
  1699.  
  1700. OSErr TFileBasedDocument::FileChanged(Boolean checkType)
  1701. {
  1702.     HParamBlockRec pb;
  1703.     OSErr err = noErr;
  1704.  
  1705.     if (fFileExists)
  1706.     {
  1707.         err = fFile->GetFileInfo(pb);
  1708.     
  1709.         if (err == noErr)
  1710.         {
  1711.             if (checkType && (pb.fileParam.ioFlFndrInfo.fdType != fFile->fFileType))
  1712.                 err = errFTypeChanged;
  1713.             else if (fFile->IsModified())
  1714.                 err = errFileChanged;
  1715.         }
  1716.     }
  1717.     return err;
  1718. }
  1719.  
  1720. //----------------------------------------------------------------------------------------
  1721. // TFileBasedDocument::FileExists: 
  1722. //----------------------------------------------------------------------------------------
  1723. #pragma segment MAFile
  1724.  
  1725. Boolean TFileBasedDocument::FileExists()
  1726. {
  1727.     return fFileExists;
  1728. }
  1729.  
  1730. //----------------------------------------------------------------------------------------
  1731. // TFileBasedDocument::GetFile: 
  1732. //----------------------------------------------------------------------------------------
  1733. #pragma segment MADocumentRes
  1734.  
  1735. TFile* TFileBasedDocument::GetFile()
  1736. {
  1737.     return fFile;
  1738. }
  1739.  
  1740. //----------------------------------------------------------------------------------------
  1741. // TFileBasedDocument::SetFile: 
  1742. //----------------------------------------------------------------------------------------
  1743. #pragma segment MADocumentRes
  1744.  
  1745. void TFileBasedDocument::SetFile(TFile* itsNewFile)
  1746. {
  1747.     this->CloseFile();
  1748.     fFile = (TFile*)FreeIfObject(fFile);
  1749.     fFile = itsNewFile;
  1750.     fFileExists = FALSE;            // Until we are shown otherwise
  1751. }
  1752.  
  1753. //----------------------------------------------------------------------------------------
  1754. // TFileBasedDocument::GetFileName: 
  1755. //----------------------------------------------------------------------------------------
  1756. #pragma segment MADocumentRes
  1757.  
  1758. void TFileBasedDocument::GetFileName(CStr63& aName)
  1759. {
  1760.     if (fFile)
  1761.         fFile->GetName(aName);
  1762. }
  1763.  
  1764. //----------------------------------------------------------------------------------------
  1765. // TFileBasedDocument::GetSaveInfo: 
  1766. //----------------------------------------------------------------------------------------
  1767. #pragma segment MAWriteFile
  1768.  
  1769. Boolean TFileBasedDocument::GetSaveInfo(CommandNumber,
  1770.                                         Boolean copyFInfo,
  1771.                                         CInfoPBRec& cInfo)
  1772. {
  1773.     Boolean saveInfo = FALSE;
  1774.  
  1775.     if (fFileExists && copyFInfo)
  1776.     {
  1777.         OSErr err = fFile->GetCatInfo(cInfo);
  1778.         if (err == noErr)
  1779.             saveInfo = TRUE;
  1780.     }
  1781.     // set the type and creator in case it has changed; the file might be on a file server
  1782.     // and someone else could have changed the document 
  1783.     cInfo.hFileInfo.ioFlFndrInfo.fdType = fFile->fFileType;
  1784.     cInfo.hFileInfo.ioFlFndrInfo.fdCreator = fFile->fCreator;
  1785.     return saveInfo;
  1786. }
  1787.  
  1788. //----------------------------------------------------------------------------------------
  1789. // TFileBasedDocument::GetTempName: 
  1790. //----------------------------------------------------------------------------------------
  1791. #pragma segment MAWriteFile
  1792.  
  1793. void TFileBasedDocument::GetTempName(CStr63& filename)
  1794. {
  1795.     const short maxName = 31;                    //maximum name size to generate
  1796.     const short maxNumber = 10;                    //maximum # digits of the random number
  1797.     const short maxPrefix = maxName - maxNumber;
  1798.  
  1799.     CStr255 name;
  1800.     unsigned long time;
  1801.  
  1802.     // If the file is untitled, use the application name.
  1803.     if (fFile)
  1804.         fFile->GetName((CStr63 &)name);
  1805.     
  1806.     if (name.IsEmpty())
  1807.         gDispatcher->GetApplicationName(name);
  1808.         
  1809.     filename = name;
  1810.  
  1811.     // Check prefix length, and trim it down if too large.
  1812.     if (filename.Length() > maxPrefix)
  1813.         filename.Length() = (char)maxPrefix;
  1814.  
  1815.     // Append a pseudo-random number.
  1816.     GetDateTime(&time);
  1817.     NumToString((time ^ (TickCount() >> 16)) & 0x7FFF, name);    // don't have neg number
  1818.     filename += name;
  1819.  
  1820.     // Check name length, and trim it down if too large.
  1821.     if (filename.Length() > maxName)
  1822.         filename.Length() = (char)maxName;
  1823. }
  1824.  
  1825. //----------------------------------------------------------------------------------------
  1826. // TFileBasedDocument::ReadFile: 
  1827. //----------------------------------------------------------------------------------------
  1828. #pragma segment MAReadFile
  1829.  
  1830. void TFileBasedDocument::ReadFile(Boolean forPrinting)
  1831. {
  1832.     if (fFile)
  1833.     {
  1834.         OSType itsType = NULL;
  1835.         FailInfo fi;
  1836.         Try(fi)
  1837.         {
  1838.             FailOSErr(fFile->GetFileType(itsType));
  1839.             
  1840.             if (itsType != kFolderType)
  1841.             {
  1842.                 FailOSErr(fFile->OpenFile());
  1843.                 
  1844.                 // Just in case the file was left open, reset to the beginning of the file
  1845.                 fFile->SetDataMark(0, fsFromStart);
  1846.             }
  1847.  
  1848.             fFileExists = TRUE;
  1849.  
  1850.             this->DoRead(fFile, forPrinting);
  1851.  
  1852.             fi.Success();
  1853.         }
  1854.         else    // Recover
  1855.         {
  1856.             if (itsType != kFolderType)
  1857.                 this->CloseFile();
  1858.             fi.ReSignal();
  1859.         }
  1860.  
  1861.         if (itsType != kFolderType)
  1862.             FailOSErr(fFile->CloseFileIfNotKeptOpen());
  1863.  
  1864.         fFile->Modified();                        // Set the modification date 
  1865.     }
  1866. }
  1867.  
  1868. //----------------------------------------------------------------------------------------
  1869. // TFileBasedDocument::RequestFileName: 
  1870. //----------------------------------------------------------------------------------------
  1871. #pragma segment MAWriteFile
  1872.  
  1873. void TFileBasedDocument::RequestFileName(CommandNumber itsCommandNumber,
  1874.                                          Boolean /*makingCopy*/,
  1875.                                          TFile* aFile)
  1876. {
  1877.     Boolean goodReply;
  1878.  
  1879. #if !qPowerPC && !qModelCFM
  1880.     if (HasCustomFile())
  1881.     {
  1882. #endif
  1883.         CStr255 prompt;
  1884.         CStr255 filename;
  1885.         short dlgID;
  1886.         CPoint dlgLoc;
  1887.         ProcPtr dlgHook;
  1888.         ProcPtr modalFilter;
  1889.         Ptr activeList;
  1890.         ProcPtr activateProc;
  1891.         void* yourDataPtr;
  1892.         StandardFileReply customReply;
  1893.     
  1894.         this->SFPutParms(itsCommandNumber, prompt, filename, dlgID, dlgLoc, dlgHook,
  1895.                          modalFilter, activeList, activateProc, &customReply, yourDataPtr);
  1896.     
  1897.         gRsrcCheck = 0;                                //force immediate check
  1898.     
  1899.         FailOSErr(MAInteractWithUser());
  1900.     
  1901.         if (yourDataPtr == NULL)
  1902.             yourDataPtr = &itsCommandNumber;
  1903.         
  1904.         gClipboardMgr->AboutToLoseControl(TRUE);        // so scrap gets converted
  1905.  
  1906.         DlgHookYDUPP cpfDlgHook = NewDlgHookYDProc(dlgHook);
  1907.         ModalFilterYDUPP cpfModalFilter = NewModalFilterYDProc(modalFilter);
  1908.         ActivateYDUPP cpfActivateProc = NewActivateYDProc(activateProc);
  1909.  
  1910.         CustomPutFile(prompt, filename, &customReply, dlgID, dlgLoc, cpfDlgHook, cpfModalFilter, (short*)activeList, cpfActivateProc, yourDataPtr);
  1911.         
  1912.         cpfDlgHook = (DlgHookYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cpfDlgHook);
  1913.         cpfModalFilter = (ModalFilterYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cpfModalFilter);
  1914.         cpfActivateProc = (ActivateYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cpfActivateProc);
  1915.         
  1916.         gClipboardMgr->RegainControl(TRUE);            // so scrap gets converted
  1917.  
  1918.         goodReply = customReply.sfGood;
  1919.         if (goodReply)
  1920.             aFile->Specify(customReply.sfFile);        // Don't use SpecifyWithStandardFile
  1921.                                                     // here since that would clobber the
  1922.                                                     // filetype.
  1923. #if !qPowerPC && !qModelCFM
  1924.     }
  1925.     else
  1926.     {
  1927.         CStr255 prompt;
  1928.         CStr255 filename;
  1929.         short dlgID;
  1930.         CPoint dlgLoc;
  1931.         ProcPtr dlgHook;
  1932.         ProcPtr modalFilter;
  1933.         Ptr activeList;
  1934.         ProcPtr activateProc;
  1935.         void* yourDataPtr;
  1936.         SFReply reply;
  1937.     
  1938.         // We can't pass reply because it's a lowly SFReply, not a StandardFileReply
  1939.         this->SFPutParms(itsCommandNumber, prompt, filename, dlgID, dlgLoc, dlgHook,
  1940.                          modalFilter, activeList, activateProc, NULL, yourDataPtr);
  1941.     
  1942.         gRsrcCheck = 0;                                //force immediate check
  1943.     
  1944.         FailOSErr(MAInteractWithUser());
  1945.     
  1946.         if (yourDataPtr == NULL)
  1947.             yourDataPtr = &itsCommandNumber;
  1948.     
  1949.         // We will pass the address of the CallBack instead of the modalFilter to
  1950.         // SFPPutFile It will add yourDataPtr parameter before passing on to the
  1951.         // ModalFilterProc supplied by SFPutParms this lets us assume a single calling
  1952.         // convention for that function.
  1953.  
  1954.         // Don't create a CallBack when the SF callback is NULL.
  1955.         // Also, pass itsCommandNumber as a default yourDataPtr.
  1956.         
  1957.         CallBack myModalHookCallBack;
  1958.         SetCallBack(dlgHook, (long)yourDataPtr, &myModalHookCallBack);
  1959.         DlgHookProcPtr aDlgHookProcPtr = dlgHook ? (DlgHookProcPtr)&myModalHookCallBack : NULL;
  1960.  
  1961.         CallBack myModalFilterCallBack;
  1962.         SetCallBack(modalFilter, (long)yourDataPtr, &myModalFilterCallBack);
  1963.         ModalFilterProcPtr aModalFilterProcPtr = modalFilter ? (ModalFilterProcPtr)&myModalFilterCallBack : NULL;
  1964.         
  1965.         gClipboardMgr->AboutToLoseControl(TRUE);    // so scrap gets converted
  1966.         
  1967.         SFPPutFile(dlgLoc, prompt, filename, aDlgHookProcPtr, &reply, dlgID, aModalFilterProcPtr);
  1968.         
  1969.         gClipboardMgr->RegainControl(TRUE);            // so scrap gets converted
  1970.  
  1971.         goodReply = reply.good;
  1972.         if (goodReply)
  1973.             FailOSErr(aFile->SpecifyWithTrio(reply.vRefNum, 0, reply.fName));
  1974.     }
  1975. #endif
  1976.     
  1977.     if (goodReply)
  1978.     {
  1979.         // See if there is an open document with the same name.    If there is, tell it 
  1980.         // we're trying to save it again, which will ordinarily result in failure.
  1981.         TDocument* otherDoc = gDispatcher->FindDocument(aFile);
  1982.         if (otherDoc)
  1983.             otherDoc->SaveAgain(itsCommandNumber, this);
  1984.  
  1985.         // User has already confirmed deleting target in this case, so trash file and get 
  1986.         // maximum disk space. 
  1987.         OSErr err = aFile->DeleteFile();
  1988.         if ((err != noErr) && (err != fnfErr))
  1989.             Failure(err, 0);
  1990.     }
  1991.     else
  1992.         Failure(noErr, messageCancelled);            // user cancelled 
  1993. }
  1994.  
  1995. //----------------------------------------------------------------------------------------
  1996. // TFileBasedDocument::SaveFile: 
  1997. //----------------------------------------------------------------------------------------
  1998. #pragma segment MAWriteFile
  1999.  
  2000. void TFileBasedDocument::SaveFile(CommandNumber itsCommandNumber,
  2001.                                   Boolean askForFilename,
  2002.                                   Boolean copyFInfo,
  2003.                                   Boolean makingCopy)
  2004. {
  2005.     MAVolatileInit(Boolean, volatileAskForFilename, askForFilename);
  2006.     //MAVolatileInit(Boolean, volatileMakingCopy, makingCopy);    // can't be volatile because it is passed by reference
  2007.     
  2008.     long dataBytes = 0;
  2009.     long rsrcBytes = 0;
  2010.     long neededBlks;
  2011.     long usedBlks;
  2012.     long freeBlks;
  2013.     long blkSize;
  2014.     Boolean canSaveInPlace;
  2015.     CStr255 name;
  2016.     OSErr err;
  2017.     MAVolatile(Boolean, oldObjectPerm);
  2018.     MAVolatileInit(TFile*, theSaveFile, NULL);
  2019.  
  2020.     FailInfo fi;
  2021.     Try(fi)
  2022.     {
  2023.         // This can't fail or we won't be able to save in low memory conditions.
  2024.         oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  2025.         theSaveFile = this->DoMakeFile(itsCommandNumber);
  2026.         AllocateObjectsFromPerm(oldObjectPerm);
  2027.  
  2028.         if (volatileAskForFilename)
  2029.             this->RequestFileName(itsCommandNumber, makingCopy, theSaveFile);
  2030.         else
  2031.             theSaveFile->SpecifyWithFile(fFile);
  2032.  
  2033.         theSaveFile->SetPermissions(fsRdWrPerm, fsRdWrPerm);// Since we intend to write to it 
  2034.  
  2035.         this->AboutToSaveFile(theSaveFile, itsCommandNumber, makingCopy);
  2036.  
  2037.         // Get information about the volume saving to 
  2038.         FailOSErr(theSaveFile->GetFreeBlocks(freeBlks));
  2039.  
  2040.         // Don't fill the disk completely.
  2041.         freeBlks--;
  2042.  
  2043.         // compute size needed to save document 
  2044.         FailOSErr(theSaveFile->GetBlockSize(blkSize));
  2045.  
  2046.         this->DoNeedDiskSpace(theSaveFile, dataBytes, rsrcBytes);
  2047.         neededBlks = NumBlocks(rsrcBytes, blkSize) + NumBlocks(dataBytes, blkSize);
  2048.  
  2049.         // If there is enough space we're done.  Save the file by the method specified 
  2050.         if (freeBlks >= neededBlks)
  2051.         {
  2052.             if ((fHowToSave == svtAskUser) || (fHowToSave == svtAlways))
  2053.                 this->SaveViaTemp(itsCommandNumber, makingCopy, copyFInfo, theSaveFile);
  2054.             else
  2055.                 this->SaveInPlace(itsCommandNumber, makingCopy, copyFInfo, theSaveFile);
  2056.         }
  2057.         // Is there enough space to save the file in place? 
  2058.         else
  2059.         {
  2060.             canSaveInPlace = FALSE;                // Default value 
  2061.  
  2062.             // See if we can save in place be recovering the space used by the existing file 
  2063.             err = theSaveFile->GetPhysicalSize(dataBytes, rsrcBytes);
  2064.             if (err == noErr)
  2065.             {
  2066.                 usedBlks = NumBlocks(dataBytes, blkSize) + NumBlocks(rsrcBytes, blkSize);
  2067.  
  2068.                 if (neededBlks <= usedBlks + freeBlks)
  2069.                 {
  2070.                     // Saving in place purges the existing file.  Should we ask before going ahead? 
  2071.                     if ((fHowToSave == svtAskUser) || (fHowToSave == sipAskUser))
  2072.                     {
  2073.                         FailOSErr(MAInteractWithUser());
  2074.                         theSaveFile->GetName((CStr63 &)name);
  2075.                         ParamText(name, gEmptyString, gEmptyString, gEmptyString);
  2076.                         if (MacAppAlert(phPurgeOld, NULL) == kYesButton)
  2077.                             canSaveInPlace = TRUE;
  2078.                         else
  2079.                             Failure(noErr, messageCancelled);
  2080.                     }
  2081.                     else if (fHowToSave == sipAlways)
  2082.                         canSaveInPlace = TRUE;
  2083.                 }
  2084.             }
  2085.             // If no file to recover space from, signal disk full error.  Otherwise just display error 
  2086.             else if (err != fnfErr)
  2087.                 Failure(err, 0);
  2088.  
  2089.             if (canSaveInPlace)
  2090.                 this->SaveInPlace(itsCommandNumber, makingCopy, copyFInfo, theSaveFile);
  2091.             else
  2092.                 Failure(dskFulErr, 0);
  2093.         }
  2094.  
  2095. #if qDebugMsg
  2096.         err = theSaveFile->GetPhysicalSize(dataBytes, rsrcBytes);
  2097.         if (err == noErr)
  2098.         {
  2099.             usedBlks = NumBlocks(dataBytes, blkSize) + NumBlocks(rsrcBytes, blkSize);
  2100.             if (usedBlks != neededBlks)
  2101.             {
  2102.                 fprintf(stderr, "In TFileBasedDocument::SaveFile: DoNeedDiskSpace estimated disk space incorrectly.\n");
  2103.                 fprintf(stderr, "estimated # disk blocks = %ld\n", neededBlks);
  2104.                 fprintf(stderr, "   actual # disk blocks = %ld\n", usedBlks);
  2105.             }
  2106.         }
  2107. #endif
  2108.  
  2109.         if (!makingCopy)
  2110.         {
  2111.             theSaveFile->GetName((CStr63 &)name);
  2112.             this->FileHasBeenSaved(name);
  2113.  
  2114.             fFileExists = TRUE;
  2115.             fFile->SpecifyWithFile(theSaveFile);
  2116.             fFile->Modified();
  2117.             FailOSErr(fFile->OpenFileIfKeptOpen());
  2118.         }
  2119.  
  2120.         fi.Success();
  2121.     }
  2122.     else    // Recover
  2123.     {
  2124.         // Make sure that we continue to allocate objects from the right place.
  2125.         AllocateObjectsFromPerm(oldObjectPerm);
  2126.         
  2127.         if (theSaveFile)
  2128.         {
  2129.             err = theSaveFile->FlushVolume();
  2130.             if (fi.message == 0)
  2131.                 theSaveFile->GetName((CStr63 &)gErrorParm3);
  2132.             theSaveFile = (TFile *)FreeIfObject(theSaveFile);
  2133.         }
  2134.  
  2135.         long newMsg;
  2136.  
  2137.         if (!volatileAskForFilename)
  2138.             newMsg = messageSaveFailed;
  2139.         else if (makingCopy)
  2140.             newMsg = messageSaveCopyFailed;
  2141.         else
  2142.             newMsg = messageSaveAsFailed;
  2143.  
  2144.         FailNewMessage(fi.error, fi.message, newMsg);
  2145.     }
  2146.  
  2147.     err = theSaveFile->FlushVolume();
  2148.  
  2149.     theSaveFile->Free();
  2150. }
  2151.  
  2152. //----------------------------------------------------------------------------------------
  2153. // TFileBasedDocument::SaveInPlace: 
  2154. //----------------------------------------------------------------------------------------
  2155. #pragma segment MAWriteFile
  2156.  
  2157. void TFileBasedDocument::SaveInPlace(CommandNumber itsCommandNumber,
  2158.                                      Boolean makingCopy,
  2159.                                      Boolean copyFInfo,
  2160.                                      TFile* itsFile)
  2161. {
  2162.     MAVolatileInit(TFile*, volatileItsFile, itsFile);
  2163.  
  2164.     CInfoPBRec cInfo;
  2165.     Boolean validInfo = this->GetSaveInfo(itsCommandNumber, copyFInfo, cInfo);
  2166.  
  2167.     this->CloseFile();                                // close the file 
  2168.     
  2169.     {
  2170.         OSErr err = volatileItsFile->DeleteFile();
  2171.         if ((err != noErr) && (err != fnfErr))
  2172.             Failure(err, 0);
  2173.     }
  2174.  
  2175.     FailInfo fi;
  2176.     Try(fi)
  2177.     {
  2178.         FailOSErr(volatileItsFile->CreateFile());
  2179.  
  2180.         if (validInfo)                            // Change attributes of volatileItsFile?
  2181.             FailOSErr(volatileItsFile->SetCatInfo(cInfo));
  2182.  
  2183.         FailOSErr(volatileItsFile->OpenFile());
  2184.  
  2185.         this->DoWrite(volatileItsFile, makingCopy);
  2186.  
  2187.         fi.Success();
  2188.     }
  2189.     else    // Recover
  2190.     {
  2191.         OSErr recoverErr;
  2192.  
  2193.         recoverErr = volatileItsFile->CloseFile();
  2194. #if qDebugMsg
  2195.         if (recoverErr != noErr)
  2196.             fprintf(stderr, "In SaveInPlace recovery: error from CloseFile is %d\n", recoverErr);
  2197. #endif
  2198.  
  2199.         recoverErr = volatileItsFile->DeleteFile();
  2200. #if qDebugMsg
  2201.         if ((recoverErr != noErr) && (recoverErr != fnfErr))
  2202.             fprintf(stderr, "In SaveInPlace recovery: error from DeleteFile is %d\n", recoverErr);
  2203. #endif
  2204.  
  2205.         fi.ReSignal();
  2206.     }
  2207.  
  2208.     FailOSErr(volatileItsFile->CloseFile());
  2209. }
  2210.  
  2211. //----------------------------------------------------------------------------------------
  2212. // TFileBasedDocument::SaveViaTemp: 
  2213. //----------------------------------------------------------------------------------------
  2214. #pragma segment MAWriteFile
  2215.  
  2216. void TFileBasedDocument::SaveViaTemp(CommandNumber itsCommandNumber,
  2217.                                      Boolean makingCopy,
  2218.                                      Boolean copyFInfo,
  2219.                                      TFile* itsFile)
  2220. {
  2221.     MAVolatileInit(TFile*, volatileItsFile, itsFile);
  2222.     MAVolatileInit(Boolean, volatileMakingCopy, makingCopy);
  2223.     
  2224.     CInfoPBRec cInfo;
  2225.     Boolean validInfo = this->GetSaveInfo(itsCommandNumber, copyFInfo, cInfo);
  2226.  
  2227.     FSSpec saveFileSpec;
  2228.     volatileItsFile->GetFileSpec(saveFileSpec);        // Save file spec since it may be clobbered 
  2229.  
  2230.     CStr63     tmpName;    // not volatile...passed as const&
  2231.     this->GetTempName(tmpName);
  2232.  
  2233.     short tmpVRefNum;
  2234.     long tmpDirID;
  2235.     FailOSErr(FindFolder(saveFileSpec.vRefNum, kTemporaryFolderType, kCreateFolder, &tmpVRefNum, &tmpDirID));
  2236.     FailOSErr(volatileItsFile->SpecifyWithTrio(tmpVRefNum, tmpDirID, tmpName));
  2237.  
  2238.     FailInfo fi;
  2239.     Try(fi)
  2240.     {
  2241.         FailOSErr(volatileItsFile->CreateFile());
  2242.  
  2243.         if (validInfo)                            // Change attributes of volatileItsFile??
  2244.             FailOSErr(volatileItsFile->SetCatInfo(cInfo));
  2245.         FailOSErr(volatileItsFile->OpenFile());
  2246.  
  2247.         this->DoWrite(volatileItsFile, volatileMakingCopy);
  2248.  
  2249.         fi.Success();
  2250.     }
  2251.     else    // Recover
  2252.     {
  2253.         OSErr recoverErr;
  2254.  
  2255.         recoverErr = volatileItsFile->CloseFile();
  2256.         
  2257. #if qDebugMsg
  2258.         if (recoverErr != noErr)
  2259.             fprintf(stderr, "In SaveViaTemp error recovery: error from CloseFile is %d\n", recoverErr);
  2260. #endif
  2261.  
  2262.         recoverErr = volatileItsFile->DeleteFile();
  2263.         
  2264. #if qDebugMsg
  2265.         if ((recoverErr != noErr) && (recoverErr != fnfErr))
  2266.             fprintf(stderr, "In SaveViaTemp error recovery: error from volatileItsFile.DeleteFile is %d\n", recoverErr);
  2267. #endif
  2268.  
  2269.         fi.ReSignal();
  2270.     }
  2271.  
  2272.     FailOSErr(volatileItsFile->CloseFile());
  2273.  
  2274.     if (!volatileMakingCopy)
  2275.         this->CloseFile();                            // Close the documents file 
  2276.  
  2277.     Try(fi)
  2278.     {
  2279.         if (fFileExists && copyFInfo)
  2280.         {
  2281.             // Since ExchangeFiles doesn't check that the destination file is locked
  2282.             // we need to check ourselves.
  2283.             CInfoPBRec cInfo;
  2284.         
  2285.             BlockSet((Ptr) & cInfo, sizeof(CInfoPBRec), 0x00);// zero-out our storage 
  2286.             FailOSErr(fFile->GetCatInfo(cInfo));
  2287.             
  2288.             if (cInfo.hFileInfo.ioFlAttrib & 0x01)
  2289.                 FailOSErr(fLckdErr);
  2290.                 
  2291.             // Exchange the existing file for the one in the temporary folder… 
  2292.             FailOSErr(volatileItsFile->ExchangeFiles(fFile));
  2293.  
  2294.             // and delete the one left in the temporary folder 
  2295.             OSErr err = volatileItsFile->DeleteFile();
  2296.             if ((err != noErr) && (err != fnfErr))
  2297.                 Failure(err, 0);
  2298.         }
  2299.         else
  2300.             // The temp file was created in the temporary directory.
  2301.             // Move it back where it belongs
  2302.             FailOSErr(volatileItsFile->MoveAndRename(saveFileSpec));
  2303.  
  2304.         // Specify the file again since it may have changed if it was saved in a temporary folder 
  2305.         volatileItsFile->Specify(saveFileSpec);
  2306.  
  2307.         fi.Success();
  2308.     }
  2309.     else    // Recover
  2310.     {
  2311.         OSErr recoverErr = volatileItsFile->DeleteFile();
  2312.         
  2313. #if qDebugMsg
  2314.         if ((recoverErr != noErr) && (recoverErr != fnfErr))
  2315.             fprintf(stderr, "In SaveViaTemp error recovery: error from DeleteFile is %d\n", recoverErr);
  2316. #endif
  2317.         
  2318.         if (fFileExists && !volatileMakingCopy)
  2319.             recoverErr = fFile->OpenFileIfKeptOpen();
  2320.             
  2321. #if qDebugMsg
  2322.         if (recoverErr != noErr)
  2323.             fprintf(stderr, "In SaveViaTemp error recovery: error from OpenFileIfKeptOpen is %d\n", recoverErr);
  2324. #endif
  2325.  
  2326.         // Set the name to something intelligent in case we have to display it to the user.
  2327.         volatileItsFile->SetName(saveFileSpec.name);
  2328.         
  2329.         fi.ReSignal();
  2330.     }
  2331.  
  2332. }
  2333.  
  2334. //----------------------------------------------------------------------------------------
  2335. // TFileBasedDocument::SetFileName: 
  2336. //----------------------------------------------------------------------------------------
  2337. #pragma segment MADocumentRes
  2338.  
  2339. void TFileBasedDocument::SetFileName(const CStr63& aName)
  2340. {
  2341.     if (fFile)
  2342.         fFile->SetName(aName);
  2343. }
  2344.  
  2345. //----------------------------------------------------------------------------------------
  2346. // TFileBasedDocument::ValidateFileSpec: 
  2347. //----------------------------------------------------------------------------------------
  2348. #pragma segment MADocumentRes
  2349.  
  2350. Boolean TFileBasedDocument::ValidateFileSpec()
  2351. {
  2352.     return (fFile != NULL) ? fFile->UpdateFileSpec() : FALSE;
  2353. }
  2354.  
  2355. //----------------------------------------------------------------------------------------
  2356. // Scripting
  2357. //----------------------------------------------------------------------------------------
  2358.  
  2359. //----------------------------------------------------------------------------------------
  2360. // TFileBasedDocument::CountContainedObjects: 
  2361. //----------------------------------------------------------------------------------------
  2362. #pragma segment OSLDispatchRes
  2363.  
  2364. long TFileBasedDocument::CountContainedObjects(DescType desiredType)
  2365. {
  2366.     if (desiredType == cFile)
  2367.     {
  2368.         if (this->FileExists())
  2369.             return 1;
  2370.         else
  2371.             return 0;
  2372.     }
  2373.     else
  2374.         return TDocument::CountContainedObjects(desiredType);
  2375. }
  2376.  
  2377. //----------------------------------------------------------------------------------------
  2378. // TFileBasedDocument::GetContainedObject: 
  2379. //----------------------------------------------------------------------------------------
  2380. #pragma segment OSLDispatchRes
  2381.  
  2382. MScriptableObject* TFileBasedDocument::GetContainedObject(DescType desiredType,
  2383.                                               DescType selectionForm,
  2384.                                               const CAEDesc& selectionData)
  2385. {
  2386.     MScriptableObject * result = NULL;
  2387.     if (desiredType == cFile)
  2388.     {
  2389.         if (this->FileExists())
  2390.         {
  2391.             if (selectionForm == formName)
  2392.             {
  2393.                 TFile * resultFile = this->DoMakeFile(cOpen);
  2394.                 CStr255 thePathName;
  2395.                 selectionData.GetString(thePathName);
  2396.                 resultFile->SpecifyWithTrio(0, 0, (CStr63 &)thePathName);
  2397.                 TOSADispatcher::fgDispatcher->AddTemporaryToken(resultFile);
  2398.                 result = resultFile;
  2399.             }
  2400.             else
  2401.             {
  2402.                 TFile * myFile = GetFile();
  2403.                 if (myFile)
  2404.                 {
  2405.                     TFile * resultFile = this->DoMakeFile(cOpen);
  2406.                     resultFile->SpecifyWithFile(myFile);
  2407.                     TOSADispatcher::fgDispatcher->AddTemporaryToken(resultFile);
  2408.                     result = resultFile;
  2409.                 }
  2410.             }
  2411.         }
  2412.     }
  2413.     else
  2414.         result = Inherited::GetContainedObject(desiredType, selectionForm, selectionData);
  2415.     return result;
  2416. }
  2417.  
  2418. //----------------------------------------------------------------------------------------
  2419. // Container Application Support
  2420. //----------------------------------------------------------------------------------------
  2421.  
  2422. #if qContainer
  2423.  
  2424. //----------------------------------------------------------------------------------------
  2425. // TFileBasedDocument::MakeDatedUniqueFSSpec - Static
  2426. //----------------------------------------------------------------------------------------
  2427. #pragma segment AOpen
  2428.  
  2429. void TFileBasedDocument::MakeDatedUniqueFSSpec(FSSpec* fsSpec)
  2430. {
  2431.     static short index = 1;
  2432.     
  2433.     CStr32 tmpName(fsSpec->name);
  2434.     
  2435.     {
  2436.         CStr32 dateString;
  2437.         unsigned long secs;
  2438.         
  2439.         GetDateTime(&secs);
  2440.         DateString(secs, shortDate, dateString, NULL);
  2441.         
  2442.         // ••• MDR
  2443.         #if 1
  2444.             tmpName = tmpName + " " + dateString;
  2445.             tmpName = tmpName + " ";
  2446.         #else
  2447.             tmpName = tmpName + "\p " + dateString;
  2448.             tmpName = tmpName + "\p ";
  2449.         #endif
  2450.     }
  2451.     
  2452.     FInfo ignore;
  2453.     
  2454.     do
  2455.     {
  2456.         CStr32 indexString;
  2457.         NumToString(index, indexString);
  2458.         
  2459.         CStr32(tmpName + indexString).CopyTo(fsSpec->name);
  2460.         ++index;
  2461.         
  2462.     } while (FSpGetFInfo(fsSpec, &ignore) == noErr);
  2463. }
  2464.  
  2465. //----------------------------------------------------------------------------------------
  2466. // TFileBasedDocument::GetContainer: 
  2467. //----------------------------------------------------------------------------------------
  2468. #pragma segment MADocumentRes
  2469.  
  2470. CADocumentRef TFileBasedDocument::GetContainer()
  2471. {
  2472.     return fContainerDocument;
  2473. }
  2474.  
  2475. //----------------------------------------------------------------------------------------
  2476. // TFileBasedDocument::AddODPartView: 
  2477. //----------------------------------------------------------------------------------------
  2478. #pragma segment MADocumentRes
  2479.  
  2480. void TFileBasedDocument::AddODPartView(TODPartView* aNewODPartView)
  2481. {
  2482.     if (fODPartViewList)
  2483.         fODPartViewList->Insert((TObject*)aNewODPartView);
  2484. }
  2485.  
  2486. //----------------------------------------------------------------------------------------
  2487. // TFileBasedDocument::DeleteODPartView: 
  2488. //----------------------------------------------------------------------------------------
  2489. #pragma segment MADocumentRes
  2490.  
  2491. void TFileBasedDocument::DeleteODPartView(TODPartView* partViewToRemove)
  2492. {
  2493.     if (fODPartViewList)
  2494.         fODPartViewList->Delete((TObject*)partViewToRemove);
  2495. }
  2496.  
  2497. //----------------------------------------------------------------------------------------
  2498. // TFileBasedDocument::RegisterCAHandlers: 
  2499. //----------------------------------------------------------------------------------------
  2500. #pragma segment AOpen
  2501.  
  2502. void TFileBasedDocument::RegisterCAHandlers()
  2503. {
  2504.     if (fContainerDocument)
  2505.     {
  2506.         CAInstallFocusNotification(
  2507.                                     TDispatcher::FocusAcquiredProc,
  2508.                                     TDispatcher::FocusLostProc,
  2509.                                     fContainerDocument );
  2510.         FailOSErr(CAError());
  2511.     
  2512.         CAInstallWindowActivateHandler(
  2513.                                     TDispatcher::WindowActivateHandler,
  2514.                                     fContainerDocument );
  2515.         FailOSErr(CAError());
  2516.     
  2517.         CAInstallFrameShapeRequestHandler(
  2518.                                     TDispatcher::FrameShapeRequestHandler,
  2519.                                     fContainerDocument );
  2520.         FailOSErr(CAError());
  2521.     
  2522.         CAInstallBorderAdjuster(
  2523.                                     fContainerDocument,
  2524.                                     TDispatcher::AdjustBorderHandler );
  2525.         FailOSErr(CAError());
  2526.     }
  2527. }
  2528.  
  2529. #endif
  2530.  
  2531. //----------------------------------------------------------------------------------------
  2532. // End of UFileBasedDocument.cp
  2533.  
  2534. #pragma segment Inline
  2535.